home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJSRC111.ZIP / go32 / mswitch.asm < prev    next >
Assembly Source File  |  1993-11-12  |  11KB  |  536 lines

  1. ; This is file MSWITCH.ASM
  2. ;
  3. ; Copyright (C) 1993 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. ;
  5. ; This file is distributed under the terms listed in the document
  6. ; "copying.dj", available from DJ Delorie at the address above.
  7. ; A copy of "copying.dj" should accompany this file; if not, a copy
  8. ; should be available from where this file was obtained.  This file
  9. ; may not be distributed without a verbatim copy of "copying.dj".
  10. ;
  11. ; This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. ;
  14.  
  15. ; Modified for VCPI Implement by Y.Shibata Aug 5th 1991
  16. ;    History:191,1
  17.     title    switch between real and protected mode
  18.     .386p
  19.  
  20.     include segdefs.inc
  21.     include tss.inc
  22.     include gdt.inc
  23.     include idt.inc
  24.     include vcpi.inc
  25.  
  26. ;------------------------------------------------------------------------
  27.  
  28.     start_data16
  29.  
  30.     extrn    _gdt:gdt_s
  31.     extrn    _idt:idt_s
  32.     extrn    _gdt_phys:gdt_s
  33.     extrn    _idt_phys:gdt_s
  34.     extrn    _tss_ptr:word
  35.     extrn    _screen_seg:word
  36.     extrn    _use_xms:word
  37.     extrn    _hard_master_lo:byte
  38.     extrn    _hard_master_hi:byte
  39.     extrn    _hard_slave_lo:byte
  40.     extrn    _hard_slave_hi:byte
  41.  
  42.     extrn    _vcpi_installed:word    ;VCPI Installed set this not Zero
  43.     extrn    _vcpi_entry:fword
  44.     extrn    _abs_client:dword
  45.  
  46.     public  _was_exception
  47. _was_exception  dw    0    ; exceptions set this to 1
  48.  
  49.     public  _dr
  50. _dr    label    dword
  51. _dr0    dd    0
  52. _dr1    dd    0
  53. _dr2    dd    0
  54. _dr3    dd    0
  55.     dd    0
  56.     dd    0
  57. _dr6    dd    0
  58. _dr7    dd    0
  59.  
  60.     end_data16
  61.  
  62. ;------------------------------------------------------------------------
  63.  
  64.     .286c
  65.     start_bss
  66.  
  67.     extrn    _i_tss:tss_s
  68.     extrn    _v74_tss:tss_s
  69.     extrn    _v78_tss:tss_s
  70.     extrn    _v79_tss:tss_s
  71.     extrn    _topline_info:word
  72.  
  73.     public  _c_tss, _a_tss, _o_tss, _p_tss, _f_tss, _ed_tss, _r_tss
  74. _c_tss  label    tss_s    ; for "real mode" state
  75.     db    type tss_s dup (?)
  76. _a_tss  label    tss_s    ; for running program
  77.     db    type tss_s dup (?)
  78. _o_tss  label    tss_s    ; for convenience functions
  79.     db    type tss_s dup (?)
  80. _p_tss  label    tss_s    ; for page faults
  81.     db    type tss_s dup (?)
  82. _f_tss  label    tss_s    ; for page handling
  83.     db    type tss_s dup (?)
  84. _ed_tss label    tss_s    ; for external debuggers
  85.     db    type tss_s dup (?)
  86. _r_tss  label    tss_s    ; for real-mode callbacks
  87.     db    type tss_s dup (?)
  88.  
  89. temp_87c    dw    1 dup (?)
  90. temp_87s    dw    1 dup (?)
  91.  
  92.     end_bss
  93.     .386p
  94.  
  95. ;------------------------------------------------------------------------
  96.  
  97. sound    macro
  98.     local    wait_loop
  99.     local    wait_loop1
  100.     mov    al,033h
  101.     out    061h,al
  102.     mov    ecx,100000h
  103. wait_loop:
  104.     loopd    wait_loop
  105.     mov    al,032h
  106.     out    61h,al
  107.     mov    ecx,100000h
  108. wait_loop1:
  109.     loop    wait_loop1
  110.     endm
  111.  
  112.     start_code16
  113.  
  114.     extrn    _xms_local_enable_a20:near
  115.     extrn    _xms_local_disable_a20:near
  116.  
  117. real_stack    dd    ?
  118. real_idt    dw    0400h, 0000h, 0000h
  119. imask1        db    ?
  120. imask2        db    ?
  121.  
  122.     public  _go32
  123. _go32    proc    near
  124.     push    si
  125.     push    di
  126.     push    bx
  127. _go32_1:
  128.     mov    ax,DGROUP
  129.     mov    dx,0
  130.     shld    dx,ax,4
  131.     shl    ax,4
  132.     add    ax,_tss_ptr
  133.     adc    dx,0
  134.     mov    _gdt[g_atss].base0,ax
  135.     mov    _gdt[g_atss].base1,dl
  136.     mov    _gdt[g_atss].base2,dh
  137.     mov    bx,_tss_ptr
  138.     and    [bx].tss_eflags,  0ffffbdffh    ; clear NT flag
  139.     and    _c_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  140.     and    _i_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  141.     and    _p_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  142.     and    _f_tss.tss_eflags,0ffffbdffh    ; clear NT flag
  143.     and    _v74_tss.tss_eflags,0ffffbdffh  ; clear NT flag
  144.     and    _v78_tss.tss_eflags,0ffffbdffh  ; clear NT flag
  145.     and    _v79_tss.tss_eflags,0ffffbdffh  ; clear NT flag
  146.     or    _a_tss.tss_eflags,000000200h    ; set IE flag for a_tss only
  147.     or    _ed_tss.tss_eflags,000000200h    ; set IE flag for a_tss only
  148.  
  149.     and    _gdt[g_ctss].stype,0FDh        ; clear busy flag
  150.     and    _gdt[g_atss].stype,0FDh        ; clear busy flag
  151.     and    _gdt[g_itss].stype,0FDh        ; clear busy flag
  152.     and    _gdt[g_ptss].stype,0FDh        ; clear busy flag
  153.     and    _gdt[g_v74].stype,0FDh        ; clear busy flag
  154.     and    _gdt[g_v78].stype,0FDh        ; clear busy flag
  155.     and    _gdt[g_v79].stype,0FDh        ; clear busy flag
  156.  
  157.     mov    _was_exception,0
  158.  
  159.     ; set real_stack for return from _go32
  160.     mov    word ptr cs:real_stack,sp
  161.     mov    word ptr cs:real_stack+2,ss
  162.     mov    eax,0
  163.     mov    ax,sp
  164.     mov    esp,eax        ; make sure it's OK
  165.  
  166.     cli
  167.  
  168.     cmp    _topline_info,0
  169.     je    no_topline1
  170.     mov    ax,_screen_seg
  171.     mov    es,ax
  172.     mov    word ptr es:[2], 0b00h+'P'
  173.     mov    word ptr es:[0], 0b00h+' '
  174. no_topline1:
  175.  
  176.     in    al,21h
  177.     mov    cs:imask1,al
  178.  
  179.     in    al,0a1h
  180.     mov    cs:imask2,al
  181.     or    al,20h
  182.     mov    al,0dfh
  183.     out    0a1h,al
  184.  
  185.     call    set_a20
  186.     cmp    _vcpi_installed,0
  187.     je    short real_to_protect    ;Not VCPI Mode
  188.     mov    esi,_abs_client
  189.     mov    ax,VCPI_MODE_CHANGE
  190.     int    VCPI_REQ        ;Change Protect Mode
  191. end_loop0:
  192.     jmp    short end_loop0        ;Never Come here!! Safety Loop
  193.  
  194. real_to_protect:
  195.     lgdt    fword ptr _gdt_phys
  196.     lidt    fword ptr _idt_phys
  197.  
  198.     mov    eax,cr0
  199.     or    al,1
  200.     mov    cr0,eax        ; we're in protected mode!
  201.     db    0eah        ; JMP
  202.     dw    offset go_protect_far_jump
  203.     dw    g_rcode
  204. ;
  205. ;    Entry Protect Mode
  206. ;
  207.     public  _protect_entry
  208. _protect_entry  label    near
  209.  
  210. go_protect_far_jump:
  211.     cli
  212.     mov    ax,g_rdata
  213.     mov    ds,ax
  214.     mov    es,ax
  215.     mov    ss,ax
  216.     mov    sp,word ptr cs:real_stack  ;Need VCPI Inialize
  217.     mov    ax,g_core
  218.     mov    fs,ax
  219.     mov    gs,ax
  220.     mov    eax,0
  221.     mov    cr2,eax ; so we can tell INT 0D from page fault
  222.  
  223.  
  224.     mov    eax,_dr0
  225.     mov    dr0,eax
  226.     mov    eax,_dr1
  227.     mov    dr1,eax
  228.     mov    eax,_dr2
  229.     mov    dr2,eax
  230.     mov    eax,_dr3
  231.     mov    dr3,eax
  232.     mov    eax,_dr7
  233.     mov    dr7,eax
  234.  
  235.     cmp    _vcpi_installed,0
  236.     jne    short set_paging_far_jump    ;Now Paging Mode in VCPI
  237.     mov    bx,_tss_ptr
  238.     mov    eax,[bx].tss_cr3
  239.     cmp    eax,0
  240.     je    set_paging_far_jump
  241.     mov    cr3,eax
  242.     mov    eax,cr0
  243.     or    eax,80000000h
  244.     mov    cr0,eax        ; paging enabled!
  245.     db    0eah
  246.     dw    offset set_paging_far_jump
  247.     dw    g_rcode
  248. set_paging_far_jump:
  249.  
  250.     mov    bx,_tss_ptr
  251.     cmp    _vcpi_installed,0
  252.     jne    short no_tss_load    ;Now Paging Mode in VCPI
  253.     mov    ax,g_ctss
  254.     ltr    ax
  255. no_tss_load:
  256.     jmpt    g_atss        ; load state from VCPU
  257.  
  258. _go32    endp
  259.  
  260. ; _go_real_mode must follow the task jump, so a task jump to return
  261. ; is valid
  262.  
  263.     public  _go_real_mode
  264. _go_real_mode    proc    near
  265.  
  266.     cli
  267.     mov    ax,g_rdata
  268.     mov    ds,ax
  269.     mov    es,ax
  270.     mov    fs,ax
  271.     mov    gs,ax
  272.     mov    ss,ax
  273.  
  274.     mov    eax,dr6
  275.     mov    _dr6,eax
  276.     ;
  277.     cmp    _vcpi_installed,0
  278.     je    short protect_to_real
  279.     ;
  280.     clts                ;TS Clear
  281. ;    mov    esp,offset _c_tss.tss_stack    ;Local Stack
  282.     mov    eax,DGROUP
  283.     push    eax            ;GS
  284.     push    eax            ;FS
  285.     push    eax            ;DS
  286.     push    eax            ;ES
  287.     push    eax            ;SS
  288.     movzx    eax,word ptr cs:real_stack
  289.     push    eax            ;ESP
  290.     pushfd                ;EFLAGS
  291.     mov    eax,_TEXT
  292.     push    eax            ;CS
  293.     mov    eax,offset back_to_v86
  294.     push    eax            ;EIP
  295.     movzx    esp,sp
  296.     ;
  297.     mov    ax,g_core
  298.     mov    ds,ax
  299.     mov    ax,VCPI_MODE_CHANGE
  300.     call    fword ptr es:_vcpi_entry
  301. end_loop1:
  302.     jmp    short end_loop1        ;Never Come here!! Safety Loop
  303.  
  304. protect_to_real:
  305.     mov    eax,cr0
  306.     and    eax,07ffffff6h ; clear PE, TS, PG
  307.     mov    cr0,eax
  308.  
  309.     db    0eah
  310.     dw    offset back_to_real_far_jump
  311.     dw    _TEXT
  312. ;
  313. ;    Entry Real Mode
  314. ;
  315. back_to_real_far_jump:
  316.  
  317.     lidt    fword ptr cs:real_idt
  318.     lss    sp,cs:real_stack
  319. back_to_v86:
  320.  
  321.     mov    al,cs:imask1
  322.     out    21h,al
  323.     mov    al,cs:imask2
  324.     out    0a1h,al
  325.  
  326.     cmp    _topline_info,0
  327.     je    no_topline2
  328.     mov    ax,_screen_seg
  329.     mov    es,ax
  330.     mov    word ptr es:[0], 0b00h+'R'
  331.     mov    word ptr es:[2], 0b00h+' '
  332. no_topline2:
  333.     mov    ax,DGROUP
  334.     mov    ds,ax
  335.     mov    es,ax
  336.     mov    fs,ax
  337.     mov    gs,ax
  338.  
  339.     call    reset_a20
  340.     sti
  341.  
  342.     mov    bx,_tss_ptr
  343.     mov    al,[bx].tss_irqn
  344.  
  345.         mov     cl,_hard_slave_lo
  346.         add     cl,5
  347.         cmp     al,cl
  348.         je      short not_hard  ; for NPX errors
  349.  
  350.     mov    cl,_hard_master_lo
  351.     inc    cl
  352.     cmp    al,cl
  353.     je    short not_hard  ; to check for ^C
  354.  
  355.     cmp    al,_hard_master_lo
  356.     jb    short try_slavepic
  357.     cmp    al,_hard_master_hi
  358.     ja    short try_slavepic
  359.     jmp    is_hard
  360. try_slavepic:
  361.     cmp    al,_hard_slave_lo
  362.     jb    not_hard
  363.     cmp    al,_hard_slave_hi
  364.     ja    not_hard
  365.  
  366. is_hard:
  367.     mov    byte ptr cs:[irq_d+1],al
  368.     jmp    short irq_d_jmp ; to flush the queue
  369. irq_d_jmp:
  370. irq_d    db    0cdh,0        ; generated INT opcode
  371.     jmp    _go32_1
  372.  
  373. not_hard:
  374.     pop    bx
  375.     pop    di
  376.     pop    si
  377.     ret
  378.  
  379. _go_real_mode    endp
  380.  
  381. ;------------------------------------------------------------------------
  382.  
  383. reset_a20    proc    near
  384.     cmp    _vcpi_installed,0
  385.     jne    short reset_a20_nop
  386.     cmp    _use_xms,0
  387.     je    short reset_a20_local
  388.     call    _xms_local_disable_a20
  389. reset_a20_nop:
  390.     ret
  391.  
  392. reset_a20_local:
  393.     in    al,092h        ; 092h is the system control port "A"
  394.                 ; for PS/2 models
  395.     and    al,not 2    ; this resets the A20 bit in register al
  396.     jmp    SHORT $+2    ; forget the instruction fetch
  397.     out    092h,al        ; set the A20 bit off
  398.     ret
  399. reset_a20    endp
  400.  
  401. set_a20 proc    near
  402.     cmp    _vcpi_installed,0
  403.     jne    short set_a20_nop
  404.     cmp    _use_xms,0
  405.     je    short set_a20_local
  406.     call    _xms_local_enable_a20
  407. set_a20_nop:
  408.     ret
  409.  
  410. set_a20_local:
  411.     pushf
  412.     cli
  413.     in    al,092h        ; 092h is the system control port "A"
  414.                 ; for PS/2 models
  415.     or    al,2        ; this sets the A20 bit in register al
  416.     jmp    SHORT $+2    ; forget the instruction fetch
  417.     out    092h,al        ; set the A20 bit on
  418.  
  419.     mov    ax,0
  420.     mov    fs,ax
  421.     mov    ax,0ffffh
  422.     mov    gs,ax
  423.     mov    bx,fs:[0]
  424.     mov    word ptr fs:[0],1234
  425.     cmp    word ptr gs:[16],1234
  426.     je    need_to_set_a20
  427.     mov    word ptr fs:[0],4321
  428.     cmp    word ptr gs:[16],4321
  429.     je    need_to_set_a20
  430.     mov    fs:[0],bx
  431.     popf
  432.     ret
  433.  
  434. need_to_set_a20:
  435.     mov    fs:[0],bx
  436.     call    waitkb
  437.     mov    al,0d1h
  438.     out    64h,al
  439.     call    waitkb
  440.     mov    al,0dfh        ; Patrick
  441.     out    60h,al
  442.     call    waitkb
  443.     mov    al,0ffh        ; Patrick
  444.     out    64h,al        ; Patrick
  445.     call    waitkb        ; Patrick
  446.     mov    ax,0
  447.     mov    fs,ax
  448.     mov    ax,0ffffh
  449.     mov    gs,ax
  450.     mov    bx,fs:[0]
  451.  
  452. wait_for_valid_a20:
  453.     mov    word ptr fs:[0],1234
  454.     cmp    word ptr gs:[16],1234
  455.     je    wait_for_valid_a20
  456.     mov    word ptr fs:[0],4321
  457.     cmp    word ptr gs:[16],4321
  458.     je    wait_for_valid_a20
  459.  
  460.     mov    fs:[0],bx
  461.     popf
  462.     ret
  463.  
  464. waitkb:
  465.     mov    cx,0
  466. waitkb1:
  467.     in    al,64h
  468.     test    al,2
  469.     loopnz  waitkb1
  470.     je    waitkb3
  471. waitkb2:
  472.     in    al,64h
  473.     test    al,2
  474.     loopnz  waitkb1
  475. waitkb3:
  476.     ret
  477. set_a20 endp
  478.  
  479. ;------------------------------------------------------------------------
  480.  
  481.     public    _cpumode    ; 0=real mode, 1=V86
  482. _cpumode:
  483.     smsw    ax
  484.     and    ax,1
  485.     ret
  486.  
  487. ;------------------------------------------------------------------------
  488.  
  489.     public  _cputype    ; from Intel 80486 reference manual
  490. _cputype:
  491.     pushf
  492.     pop    bx
  493.     and    bx,0fffh
  494.     push    bx
  495.     popf
  496.     pushf
  497.     pop    ax
  498.     and    ax,0f000h
  499.     cmp    ax,0f000h
  500.     jz    bad_cpu
  501.     or    bx,0f000h
  502.     push    bx
  503.     popf
  504.     pushf
  505.     pop    ax
  506.     and    ax,0f000h
  507.     jz    bad_cpu
  508.  
  509.     smsw    ax
  510.     test    ax,1
  511.     jnz    bad_mode
  512.     mov    ax,0
  513.     ret
  514.  
  515. bad_mode:
  516.     mov    ax,2
  517.     ret
  518.  
  519. bad_cpu:
  520.     mov    ax,1
  521.     ret
  522.  
  523. ;------------------------------------------------------------------------
  524.  
  525.     end_code16
  526.  
  527. ;------------------------------------------------------------------------
  528.  
  529.     start_code32
  530.  
  531.     end_code32
  532.  
  533. ;------------------------------------------------------------------------
  534.  
  535.     end
  536.